#coding=utf8
from piston.handler import AnonymousBaseHandler, BaseHandler
from piston.utils import rc, throttle
from piston.emitters import Emitter, JSONEmitter
import models
import re
import csv
import StringIO
from google.appengine.api import memcache
from django.utils.hashcompat import md5_constructor
import pickle
from django.utils import simplejson
import logging
from django.conf import settings


def get_filter_options_from(request):
    """
    Obtain filter options from GET array and return they as a dict
    """

    def strip_html_tags(text):
        """
        Remove all HTML tags from the text
        """
        return re.compile(r'<[^<]*?/?>').sub('', text)
    keys_to_filter = filter(lambda x : x.startswith('filter_by_'),
                            request.GET.iterkeys()) or []
    keys_to_filter = map(lambda x: x.replace('filter_by_', ''),
                         keys_to_filter)
    r = {} # Result
    for key in keys_to_filter:
        val = request.GET.get("filter_by_%s" % key, None)
        if val:
            r[key.replace('has_', '')] = strip_html_tags(val)
    return r


class CSVEmitter(Emitter):

    # FIXME Add fields for tecnologies and medical conditions
    # FIXME Add theraupetics to CSV
    def render(self, request):
        COLUMNS_TITLES = { \
            'SIMPLE_ROWS':
                {
                'name': 'Company name',
                'website': 'Website',
                'article': 'Article',
                'image': 'Image',
                'has_company_involved': 'Companies involved',
                'has_therapeutics': 'Therapeutics',
                'has_related_to_disease_or_medical_condition': \
                    'Disease or MC',
                'has_area_of_expertise': 'Technology focus',
                'has_develops_treatments_for_disease': 'Medical focus',
                'has_products': 'Products',
                'has__medicine_disease_causes': 'Causes',
                },
            'NAMED_ROWS': {
                'has__medicine_disease_includes_diseases': \
                    'Included diseases',}
            }

        output = StringIO.StringIO()
        seria = self.construct()['Results']
        if len(seria)==0:
            return

        csvWriter = csv.writer(output, delimiter=',', quotechar='"',
                               quoting=csv.QUOTE_NONNUMERIC)
        column_ids = []
        column_titles = []
        for k in COLUMNS_TITLES:
            for c in COLUMNS_TITLES[k]:
                if seria[0].has_key(c):
                    column_ids.append(c)
                    column_titles.append(COLUMNS_TITLES[k][c])
        csvWriter.writerow(column_titles)
        for entry in seria:
            row = []
            for k in COLUMNS_TITLES['SIMPLE_ROWS']:
                e = ''
                if entry.has_key(k):
                    r = entry.pop(k)
                    if isinstance(r, list):
                        r = ', '.join(r)
                    e = r
                if k in column_ids or e!='':
                    row.append(e)
            for k in COLUMNS_TITLES['NAMED_ROWS']:
                e = ''
                if entry.has_key(k):
                    e = ', '.join([x['name'] for x in entry.pop(k)])
                if k in column_ids or e!='':
                    row.append(e)
            csvWriter.writerow([x.replace('href="/', 'href="%s/' % \
                               settings.ROOT_URL).replace('//', '/').\
                               encode('utf-8') for x in row])
        return output.getvalue()


class CompaniesHandler(BaseHandler):
    """
    Retrieve companies list using filter options and additional
    columns passed in GET array
    """
    allowed_methods = ('GET',)

    def read(self, request):
        get_cache = md5_constructor(str(request.GET)).hexdigest()
        # FIXME
        # data = memcache.get('FreeBaseHandler.read:%s' % get_cache)
        data = None
        if data is None:
            filters = get_filter_options_from(request)
            additional_cols = map(lambda x: x.replace('col_', '').\
                replace('_', '/'),
                filter(lambda x: x.startswith('col_'),
                request.GET.iterkeys()))
            companies = list(models.CompaniesRetriever().set_filter(filters).\
                include_columns(additional_cols).sort_by('name').get())
            dump = pickle.dumps(companies)
            dump = dump if len(dump)<1000000 else None
            memcache.set('FreeBaseHandler.read:%s', dump, 60*60*24)
            r = {'Results': companies} # Response
        else:
            r = {'Results': pickle.loads(data)} # Cached response
        return r


class TechnologiesHandler(BaseHandler):
    """
    Retrieve techonologies list using filter options and additional
    columns passed in GET array
    """
    allowed_methods = ('GET',)

    def read(self, request):
        get_cache = md5_constructor(str(request.GET)).hexdigest()
        # FIXME
        # data = memcache.get('FreeBaseHandler.read:%s' % get_cache)
        data = None
        if data is None:
            filters = get_filter_options_from(request)
            additional_cols = map(lambda x: x.replace('col_', '').\
                replace('_', '/'),
                filter(lambda x: x.startswith('col_'),
                request.GET.iterkeys()))
            technologies = list(models.TechnologiesRetriever().\
                set_filter(filters).include_columns(additional_cols).\
                sort_by('name').get())
            dump = pickle.dumps(technologies)
            dump = dump if len(dump)<1000000 else None
            memcache.set('FreeBaseHandler.read:%s', dump, 60*60*24)
            r = {'Results': technologies} # Response
        else:
            r = {'Results': pickle.loads(data)} # Cached response
        return r


class MedicalConditionsHandler(BaseHandler):
    """
    Retrieve medical conditions list using filter options and additional
    columns passed in GET array
    """
    allowed_methods = ('GET',)

    def read(self, request):
        get_cache = md5_constructor(str(request.GET)).hexdigest()
        # FIXME
        # data = memcache.get('FreeBaseHandler.read:%s' % get_cache)
        data = None
        if data is None:
            filters = get_filter_options_from(request)
            additional_cols = map(lambda x: x.replace('col_', '').\
                replace('_', '/'),
                filter(lambda x: x.startswith('col_'),
                request.GET.iterkeys()))
            medical_conditions = list(models.MedicalConditionsRetriever().\
                set_filter(filters).include_columns(additional_cols).
                sort_by('name').get())
            dump = pickle.dumps(medical_conditions)
            dump = dump if len(dump)<1000000 else None
            memcache.set('FreeBaseHandler.read:%s', dump, 60*60*24)
            r = {'Results': medical_conditions} # Response
        else:
            r = {'Results': pickle.loads(data)} # Cached response
        return r


class CompanyHandler(BaseHandler):
    """
    Return information about specified company. Retrieve it from
    Freebase.
    """
    allowed_methods = ('GET',)

    def read(self, request):
        return 'Ok'
        
Emitter.register('csv', CSVEmitter, 'text/csv')
Emitter.register('csv.txt', CSVEmitter, 'text/plain; charset=utf-8')
Emitter.register('json.txt', JSONEmitter, 'text/plain; charset=utf-8')
